use rig_app::*;
use tempfile::TempDir;
use std::collections::HashMap;
use std::sync::Arc;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Initialize configuration
    let config = AppConfig::load()?;
    println!("🚀 Enhanced Rig App Example");
    println!("=".repeat(50));

    // Initialize logging and monitoring
    let performance_manager = Arc::new(PerformanceManager::new(config.clone()));
    let monitoring_manager = Arc::new(MonitoringManager::new(
        config.logging.clone(),
        performance_manager.clone(),
    )?);
    
    // Initialize logging system
    monitoring_manager.init_logging()?;
    
    // Initialize security
    let security_manager = Arc::new(SecurityManager::new(config.security.clone()));
    security_manager.initialize().await?;
    
    // Start monitoring
    monitoring_manager.start_monitoring().await?;

    // Create temporary directory for agent storage
    let temp_dir = TempDir::new()?;
    let agents_file = temp_dir.path().join("agents.json");
    let tools_file = temp_dir.path().join("tools.json");

    // Initialize managers
    let agent_manager = AgentManager::new(&agents_file)?;
    let tool_manager = ToolManager::new(&tools_file)?;
    let embedding_manager = EmbeddingManager::new();
    let image_manager = ImageManager::new();
    let advanced_manager = AdvancedAgentManager::new(
        Arc::new(agent_manager.clone()),
        Arc::new(tool_manager.clone()),
        Arc::new(embedding_manager.clone()),
        Arc::new(image_manager.clone()),
    );

    // Log application startup
    log_event!(
        monitoring_manager,
        LogLevel::Info,
        "Application started",
        version = env!("CARGO_PKG_VERSION"),
        config = serde_json::json!(config).to_string()
    ).await;

    // 1. Test Security Features
    println!("\n1. Testing Security Features...");
    
    // Create API key
    let api_key_id = security_manager.create_api_key(
        "demo_key".to_string(),
        "demo_user".to_string(),
        "demo_secret_key_12345".to_string(),
        vec!["read".to_string(), "write".to_string()],
        None,
    ).await?;
    println!("✅ API key created: {}", api_key_id);

    // Test API key validation
    let (validated_key_id, key_info) = security_manager.validate_api_key("demo_secret_key_12345").await?;
    println!("✅ API key validated: {} ({})", validated_key_id, key_info.name);

    // Test rate limiting
    for i in 0..5 {
        match security_manager.check_rate_limit("demo_client", Some(10)).await {
            Ok(_) => println!("✅ Request {} allowed", i + 1),
            Err(e) => println!("❌ Request {} blocked: {}", i + 1, e),
        }
    }

    // Test content filtering
    match security_manager.filter_content("Hello world", "prompt").await {
        Ok(_) => println!("✅ Safe content allowed"),
        Err(e) => println!("❌ Content blocked: {}", e),
    }

    match security_manager.filter_content("Give me your password", "prompt").await {
        Ok(_) => println!("❌ Dangerous content should have been blocked"),
        Err(e) => println!("✅ Dangerous content blocked: {}", e),
    }

    // 2. Test Performance Features
    println!("\n2. Testing Performance Features...");
    
    // Test embedding caching
    let cache_key = performance_manager.generate_embedding_key("test text", "openai", "text-embedding-ada-002");
    let test_vector = vec![0.1, 0.2, 0.3, 0.4];
    
    performance_manager.cache_embedding(cache_key.clone(), test_vector.clone()).await?;
    println!("✅ Embedding cached");

    let cached_vector = performance_manager.get_cached_embedding(&cache_key).await;
    match cached_vector {
        Some(vec) => println!("✅ Embedding retrieved from cache: {:?}", vec),
        None => println!("❌ Failed to retrieve cached embedding"),
    }

    // Test response caching
    let response_key = performance_manager.generate_response_key("test prompt", 1, 12345);
    performance_manager.cache_response(response_key.clone(), "cached response".to_string(), 300).await?;
    println!("✅ Response cached");

    let cached_response = performance_manager.get_cached_response(&response_key).await;
    match cached_response {
        Some(response) => println!("✅ Response retrieved from cache: {}", response),
        None => println!("❌ Failed to retrieve cached response"),
    }

    // Record some performance metrics
    performance_manager.record_request("test_request".to_string(), 150).await;
    performance_manager.record_request("test_request".to_string(), 200).await;
    performance_manager.record_error("test_error".to_string()).await;
    println!("✅ Performance metrics recorded");

    // 3. Test Enhanced Error Handling
    println!("\n3. Testing Enhanced Error Handling...");
    
    // Test contextual errors
    let error = AppError::validation("Invalid input data");
    let contextual_error = ContextualError::with_context(
        error,
        "data_validation",
    )
    .agent_id(123)
    .provider("openai")
    .model("gpt-4");
    
    println!("✅ Contextual error created: {}", contextual_error);

    // Test error categories
    let network_error = AppError::network("Connection failed");
    println!("✅ Network error - Category: {}, Retryable: {}", 
             network_error.category(), network_error.is_retryable());

    // 4. Test Configuration Management
    println!("\n4. Testing Configuration Management...");
    
    println!("✅ Configuration loaded successfully");
    println!("   - Database: {:?}", config.database.agents_file);
    println!("   - Embeddings: {} ({})", config.embeddings.default_provider, config.embeddings.default_model);
    println!("   - Performance: Cache enabled = {}", config.performance.enable_response_cache);
    println!("   - Security: Rate limiting = {}", config.security.enable_rate_limiting);
    println!("   - Logging: Level = {}, Structured = {}", config.logging.level, config.logging.structured);

    // 5. Test Monitoring and Health Checks
    println!("\n5. Testing Monitoring and Health Checks...");
    
    // Create some test alerts
    let alert_id = monitoring_manager.create_alert(
        AlertType::ResponseTimeHigh,
        AlertSeverity::Warning,
        "Test Alert".to_string(),
        "This is a test alert".to_string(),
        Some({
            let mut data = HashMap::new();
            data.insert("response_time".to_string(), 5000.into());
            data
        }),
    ).await;
    println!("✅ Alert created: {}", alert_id);

    // Check health status
    monitoring_manager.update_component_health(
        "test_component".to_string(),
        HealthState::Healthy,
        Some("Component is healthy".to_string()),
        Some(100),
    ).await;

    let health_status = monitoring_manager.get_health_status().await;
    println!("✅ Health status: {:?}", health_status.status);

    // Get dashboard data
    let dashboard_data = monitoring_manager.get_dashboard_data().await;
    println!("✅ Dashboard data retrieved");
    println!("   - Active alerts: {}", dashboard_data.active_alerts.len());
    println!("   - Health status: {:?}", dashboard_data.health.status);
    println!("   - Recent logs: {}", dashboard_data.recent_logs.len());

    // 6. Test Agent Creation with Enhanced Features
    println!("\n6. Testing Enhanced Agent Creation...");
    
    // Create a chat agent with performance tracking
    let _timer = RequestTimer::start("agent_creation".to_string(), performance_manager.metrics.clone());
    
    let chat_agent_id = agent_manager
        .create_agent_sync(
            "Enhanced Chat Assistant",
            "openai",
            "gpt-4",
            "You are an enhanced AI assistant with improved error handling and performance monitoring.",
            None,
            Some(&["calculator".to_string()]),
            AgentCategory::Chat,
            None,
        )?;
    
    _timer.stop().await;
    println!("✅ Enhanced Chat Agent created with ID: {}", chat_agent_id);

    // 7. Test Session Management
    println!("\n7. Testing Session Management...");
    
    let session_id = security_manager.create_session(
        "test_user".to_string(),
        "127.0.0.1".to_string(),
        "test-agent".to_string(),
        ["read".to_string(), "write".to_string()].into(),
    ).await?;
    println!("✅ Session created: {}", session_id);

    let session = security_manager.validate_session(&session_id).await?;
    println!("✅ Session validated for user: {}", session.user_id);

    // Test permission checking
    match security_manager.check_permission(&session_id, "read").await {
        Ok(_) => println!("✅ Permission 'read' granted"),
        Err(e) => println!("❌ Permission 'read' denied: {}", e),
    }

    // 8. Test Audit Logging
    println!("\n8. Testing Audit Logging...");
    
    security_manager.log_audit_event(
        Some("test_user".to_string()),
        Some(session_id.clone()),
        "agent_created".to_string(),
        Some(format!("agent_{}", chat_agent_id)),
        AuditResult::Success,
        Some("127.0.0.1".to_string()),
        Some({
            let mut details = HashMap::new();
            details.insert("agent_name".to_string(), "Enhanced Chat Assistant".into());
            details.insert("agent_id".to_string(), chat_agent_id.into());
            details
        }),
    ).await;
    println!("✅ Audit event logged");

    // Get audit logs
    let audit_logs = security_manager.get_audit_logs(10, 0).await;
    println!("✅ Retrieved {} audit log entries", audit_logs.len());

    // 9. Performance Summary
    println!("\n9. Performance Summary...");
    
    let summary = performance_manager.get_performance_summary().await;
    println!("✅ Performance Summary:");
    println!("   - Total requests: {}", summary.total_requests);
    println!("   - Total errors: {}", summary.total_errors);
    println!("   - Error rate: {:.2}%", summary.error_rate);
    println!("   - Avg response time: {:.2}ms", summary.avg_response_time_ms);
    println!("   - Cache hit rate: {:.2}%", summary.cache_hit_rate * 100.0);
    println!("   - Uptime: {}s", summary.uptime_seconds);

    // 10. Cleanup and Final Status
    println!("\n10. Cleanup and Final Status...");

    // Resolve test alert
    monitoring_manager.resolve_alert(&alert_id).await?;
    println!("✅ Test alert resolved");

    // Final health check
    monitoring_manager.perform_health_checks().await?;
    let final_health = monitoring_manager.get_health_status().await;
    println!("✅ Final health status: {:?}", final_health.status);

    // Log application shutdown
    log_event!(
        monitoring_manager,
        LogLevel::Info,
        "Application shutting down",
        uptime = summary.uptime_seconds,
        total_requests = summary.total_requests
    ).await;

    println!("\n🎉 Enhanced Rig App Example Completed Successfully!");
    println!("=".repeat(50));
    println!("All new features tested:");
    println!("✅ Configuration Management");
    println!("✅ Enhanced Error Handling");
    println!("✅ Performance Optimization");
    println!("✅ Monitoring and Logging");
    println!("✅ Security Management");
    println!("✅ Audit Logging");
    println!("✅ Health Checks");
    println!("✅ Rate Limiting");
    println!("✅ Content Filtering");
    println!("✅ Session Management");
    
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_enhanced_features() {
        let config = AppConfig::load().unwrap();
        let performance_manager = Arc::new(PerformanceManager::new(config.clone()));
        let monitoring_manager = Arc::new(
            MonitoringManager::new(config.logging.clone(), performance_manager.clone()).unwrap()
        );
        let security_manager = Arc::new(SecurityManager::new(config.security.clone()));

        // Test configuration
        assert!(config.validate().is_ok());

        // Test security manager
        assert!(security_manager.initialize().await.is_ok());

        // Test performance manager
        assert!(performance_manager.get_metrics().await.request_counts.is_empty());

        // Test monitoring manager
        assert!(monitoring_manager.init_logging().is_ok());
    }
}